#include "StdAfx.h"
#include "History.h"

//@author A0086933U
History::History()
{
	_noOfTransaction = 0;
	_totalExpense = 0;
	_totalIncome = 0;
}
History::~History(void)
{
}

//getter
int History::getNoOfTransaction()
{
	_noOfTransaction = _listOfTransaction.size();
	return _noOfTransaction;
}
Transaction* History::getNth(int N)
{
	list<Transaction*>::iterator iter;

	if(N<=_noOfTransaction)
	{
		iter = _listOfTransaction.begin();
		for(int i = 1; i<N; i++)
			iter++;
		return *iter;
	}
	else
		return NULL;
}
double History::getTotalExpense()
{
	return _totalExpense;
}
double History::getTotalIncome()
{
	return _totalIncome;
}
list<Transaction*>* History::getTransList()
{
	return &_listOfTransaction;
}

//functions
bool History::coutAll()
{
	int i;

	for(i=0; i<_noOfTransaction; i++)
	{
		//cout...
	}

	if(i=_noOfTransaction)
		return true;
	else
		return false;
}
bool History::checkDuplicate(Transaction *T)
{
	if(_listOfTransaction.empty())
		return false;

	list<Transaction*>::iterator iter;
	for(iter = _listOfTransaction.begin(); iter != _listOfTransaction.end(); iter++)
	{
		if(*iter == T)
			return true;
	}
	return false;
}
bool History::add(Transaction *T)
{
	if(T != NULL 
		&& !this->checkDuplicate(T))
	{
		_listOfTransaction.push_back(T);
		_noOfTransaction++;
		switch (T->getType())
		{
		case INCOME:
			_totalIncome += T->getAmount();
			break;
		case EXPENSE:
			_totalExpense += T->getAmount();
			break;
		case TRANSFER:
			break;
		}
		return true;
	}
	else
		return false;
}
History History::merge(History* H)
{
	History tempHist;
	list<Transaction*> tempList;
	tempList.merge(_listOfTransaction);
	tempList.merge(*(H->getTransList()));

	if(tempList.empty())
		return tempHist;

	list<Transaction*>::iterator iter;

	for(iter=tempList.begin(); iter!=tempList.end(); iter++)
		tempHist.add(*iter);
	(tempHist.getTransList())->sort();
	return tempHist;
}
bool History::remove(Transaction* T)
{
	if(T == NULL)
		return false;

	for(int i=1; i<=_noOfTransaction; i++)
	{
		if(this->getNth(i)==T)
		{
			switch(T->getType())
			{
			case INCOME:
				_totalIncome -= T->getAmount();
				break;
			case EXPENSE:
				_totalExpense -= T->getAmount();
				break;
			case TRANSFER:
				break;
			}
			_listOfTransaction.remove(T);
			_noOfTransaction--;
			_listOfTransaction.sort();
			return true;
		}
	}
	return false;
}
int History::remove(History* H)
{
	int count = 0;
	if(H->getNoOfTransaction() == 0)
		return count;

	for(int i=1; i<=H->getNoOfTransaction(); i++)
	{
		if(this->remove(H->getNth(i)))
			count++;
	}
	_listOfTransaction.sort();
	return count;
}
bool History::clear()
{
	if(_noOfTransaction == 0)
		return true;
	_listOfTransaction.clear();
	_noOfTransaction = 0;
	_totalExpense = 0;
	_totalIncome = 0;
	return true;
}

//filters
History History::filterCategory(string category)//by category
{
	History tempHist;
	for(int i=1; i<=_noOfTransaction; i++)
	{
		if(getNth(i)->getCategory()==category)
			tempHist.add(getNth(i));
	}
	(tempHist.getTransList())->sort();
	return tempHist;
}
History History::filterDate(struct dateTime DTStart, struct dateTime DTEnd)//by date
{
	double start = DTStart.minute/10000+DTStart.hour/100+DTStart.day+DTStart.month*100+DTStart.year*10000;
	double end = DTEnd.minute/10000+DTEnd.hour/100+DTEnd.day+DTEnd.month*100+DTEnd.year*10000;
	struct dateTime tempDT;
	double t;
	History tempHist;
	for(int i=1; i<=_noOfTransaction; i++)
	{
		tempDT = getNth(i)->getDateTime();
		t = tempDT.minute/10000+tempDT.hour/100+tempDT.day+tempDT.month*100+tempDT.year*10000;
		if(t>= start && t<= end)
			tempHist.add(getNth(i));
	}
	(tempHist.getTransList())->sort();
	return tempHist;
}
History History::filterAccount(string account)//by account
{
	History tempHist;
	for(int i=1; i<=_noOfTransaction; i++)
	{
		switch (getNth(i)->getType())
		{
		case INCOME:
		case EXPENSE:
			{
				if(getNth(i)->getAccount()==account)
					tempHist.add(getNth(i));
			}
			break;
		case TRANSFER:
			{
				if(getNth(i)->getAccountFrom()==account || getNth(i)->getAccountTo()==account)
					tempHist.add(getNth(i));
			}
			break;
		}
	}
	(tempHist.getTransList())->sort();
	return tempHist;
}
History History::filterAmount(double low, double high) //by amount
{
	History tempHist;
	for(int i=1; i<=_noOfTransaction; i++)
	{
		if(getNth(i)->getAmount()>= low && getNth(i)->getAmount()<= high)
			tempHist.add(getNth(i));
	}
	(tempHist.getTransList())->sort();
	return tempHist;
}
History History::filterType(int type)
{
	History tempHist;
	for(int i=1; i<=_noOfTransaction; i++)
	{
		if(getNth(i)->getType()==type)
			tempHist.add(getNth(i));
	}
	(tempHist.getTransList())->sort();
	return tempHist;
}